#coding=utf-8

import os

from MZCCSingleLineRuleChecker import *
from MZCCMulLineRuleChecker import *
from Model.MZCCLineCheckContext import *

from Config.MZCCRuleParser import *

'''
' 检查文件
' 输入：
'  filePath : 文件名路径
'  slRuleArray : 当行规则项数组
'  mlRuleArray : 多行规则项数组
' 输出：
'  问题项列表
'''
def mzccFileCheck(filePath, slRuleArray, mlRuleArray):

    if False == os.path.exists(filePath):
        return [];

    # 过滤注释
    noCommentFilePath = mzccWriteNoCommentFile(filePath);
    fp = open(noCommentFilePath).readlines();
    problemArray = [];
    lastNspLine = "";
    for (curLineNum, curLine) in enumerate(fp):

        curNspLine = curLine.replace(' ', '');

        lineContext = MZCCLineCheckContext();
        lineContext.curLineNum = curLineNum + 1;
        lineContext.curLine = curLine;
        lineContext.curNspLine = curNspLine;
        lineContext.lastNspLine = lastNspLine;

        #单行规则检查
        sProblems = mzccLineSingleRulesCheck(slRuleArray, lineContext);
        problemArray.extend(sProblems);

        #多行规则检查
        mProblems = mzccLineMulRulesCheck(mlRuleArray, lineContext);
        problemArray.extend(mProblems)

        #记录上行信息
        lastNspLine = curNspLine;

    # 文件长度检查
    if curLineNum > 1000:
        tmpProblem = MZCCProblemItem();
        tmpProblem.lineNum = curLine;
        tmpProblem.desc = "2.7.5.3 单个代码文件的长度不可超过1000行，请拆分文件";
        tmpProblem.ruleId = "fil2.7.5.3-1";
        problemArray.append(tmpProblem);

    mzccMulRuleBufferClear();
    return problemArray;

########################################################################
# 支持函数

'''
' 单行规则检查逻辑块
' 输入：
'  origFilePath : 原始文件路径
' 输出：
'  无注释文件路径
'''
def mzccWriteNoCommentFile(origFilePath):

    # 过滤单行注释
    fileInfo = open(origFilePath).read();
    fileInfo = re.subn(r"/\*.*?\*/", '/**/', fileInfo)[0];
    fileInfo = re.subn(r"//.*?\n", "//\n", fileInfo)[0];
    fileInfo = re.subn(r"'.+?'", "''", fileInfo)[0];
    fileInfo = re.subn(r'".+?"', '""', fileInfo)[0];

    tmpFileName = "./RunTime/mzccTmpNoCommentFile.txt"
    wfp = open(tmpFileName, "w");
    print >> wfp, fileInfo;
    wfp.close();

    # 过滤多行注释
    tmpStartFlag = False;
    fp = open(tmpFileName).readlines();
    fileInfo = "";
    for (curLineNum, curLine) in enumerate(fp):
        if True == tmpStartFlag:
            if mzccRegex(curLine, r"\*/"):
                fileInfo += re.subn(r".*\*/\n", r"\*/\n", curLine)[0];
                tmpStartFlag = False;
            else:
                fileInfo += "*\n";
            continue;
        if mzccRegex(curLine, r"/\*(?!\*/)"):
            tmpStartFlag = True;
            fileInfo += re.subn(r"/\*.*?\n", r"/\*\n", curLine)[0];
        else:
            fileInfo += curLine;

    wfp2 = open(tmpFileName, "w");
    print >> wfp2, fileInfo;
    wfp2.close();

    return tmpFileName;

'''
' 单行规则检查逻辑块
' 输入：
'  slRuleArray : 单行规则项数组
'  lineNum : 当前行号
'  curLine : 当前行
' 输出：
'  问题项列表（每项是一个问题字符串）
'''
def mzccLineSingleRulesCheck(slRuleArray, lineContext):

    problemArray = [];
    for tmpItem in slRuleArray:
        tmpProblem = mzccSingleRuleCheck(tmpItem, lineContext);
        if None != tmpProblem:
            problemArray.append(tmpProblem);
    return problemArray;

'''
' 多行规则检查逻辑块
' 输入：
'  mlRuleArray : 多行规则项数组
'  lineNum : 当前行号
'  curNspLine : 当前无空格行
'  lastNspLine : 当前无空格行
' 输出：
'  问题项列表
'''
def mzccLineMulRulesCheck(mlRuleArray, lineContext):

    problemArray = [];
    for tmpItem in mlRuleArray:
        tmpProblem = mzccMulRuleCheck(tmpItem, lineContext);
        if None != tmpProblem:
            problemArray.append(tmpProblem);
    return problemArray;

